<template>
    <div :class="classes" :style="styles" @click="back">
        <slot>
            <div :class="innerClasses">
                <i class="fa fa-arrow-up"></i>
            </div>
        </slot>
    </div>
</template>
<script>
    const prefixCls = 'x-back-top';


    function getScroll(target, top) {
        const prop = top ? 'pageYOffset' : 'pageXOffset';
        const method = top ? 'scrollTop' : 'scrollLeft';

        if (target === window) {
            return window.pageYOffset
        }
        else {
            return target.scrollTop
        }
    }

    function scrollTop(el, from = 0, to, duration = 500) {
        if (!window.requestAnimationFrame) {
            window.requestAnimationFrame = (
                window.webkitRequestAnimationFrame ||
                window.mozRequestAnimationFrame ||
                window.msRequestAnimationFrame ||
                function (callback) {
                    return window.setTimeout(callback, 1000 / 60);
                }
            );
        }
        const difference = Math.abs(from - to);
        const step = Math.ceil(difference / duration * 50);

        function scroll(start, end, step) {
            if (start === end) return;

            let d = (start + step > end) ? end : start + step;
            if (start > end) {
                d = (start - step < end) ? end : start - step;
            }

            if (el === window) {
                window.scrollTo(d, d);
            } else {
                el.scrollTop = d;
            }
            window.requestAnimationFrame(() => scroll(d, end, step));
        }

        scroll(from, to, step);
    }

    export default {
        name: 'XBackTop',
        props: {
            containerSelector: {
                type: String
            },
            height: {
                type: Number,
                default: 400
            },
            bottom: {
                type: Number,
                default: 30
            },
            right: {
                type: Number,
                default: 30
            },
            duration: {
                type: Number,
                default: 1000
            }
        },
        data () {
            return {
                backTop: false
            };
        },
        mounted () {
            this.container.addEventListener('scroll', this.handleScroll, false);
            this.container.addEventListener('resize', this.handleScroll, false);
        },
        beforeDestroy () {
            this.container.removeEventListener('scroll', this.handleScroll, false);
            this.container.removeEventListener('resize', this.handleScroll, false);
        },
        computed: {
            classes () {
                return [
                    `${prefixCls}`,
                    {
                        [`${prefixCls}-show`]: this.backTop
                    }
                ];
            },
            styles () {
                return {
                    bottom: `${this.bottom}px`,
                    right: `${this.right}px`
                };
            },
            innerClasses () {
                return `${prefixCls}-inner`;
            },
            container(){
                if (this.containerSelector) {
                    return document.querySelector(this.containerSelector)
                }
                else {
                    return window
                }
            }
        },
        methods: {
            handleScroll () {
                this.backTop = getScroll(this.container) >= this.height
            },
            back () {
                const sTop = getScroll(this.container)
                scrollTop(this.container, sTop, 0, this.duration)
                this.$emit('on-click')
            }
        }
    };
</script>
<style>
    .x-back-top {
        position: fixed;
        z-index: 999;
        cursor: pointer;
        display: none;
    }

    .x-back-top-show {
        display: block;
    }

    .x-back-top-inner {
        background-color: rgba(0, 0, 0, .6);
        border-radius: 2px;
        box-shadow: 0 1px 3px rgba(0, 0, 0, .2);
        transition: all .2s ease-in-out;
    }

    .x-back-top-inner:hover {
        background-color: rgba(0, 0, 0, .7);
    }

    .x-back-top i {
        color: #fff;
        font-size: 24px;
        padding: 8px 12px;
    }
</style>